﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Exportation;
using System.Xml.Linq;

namespace Core
{
    public partial class ExpenseReport
    {
        public static IQueryable<ExpenseReport> LoadSearchResult(DAL.DataAccessLayer dal, 
            string name, string state, Guid userId)
        {
            DataAccessDataContext db = new DataAccessDataContext();

            return from e in db.ExpenseReports
                   where e.Name.Contains(name) 
                    && e.State.Contains(state) 
                    && e.UserId.Equals(userId)
                   select e;
        }

        public static void Delete(DAL.DataAccessLayer dal, Guid id)
        {
            //apagar as linhas
            DataAccessDataContext db = dal.DataContext;
            ExpenseReport report = db.ExpenseReports.FirstOrDefault(r => r.Id == id);
            if (report != null)
            {
                List<Guid> ids = new List<Guid>();
                foreach (ExpenseLine el in report.ExpenseLines)
                {
                    ids.Add(el.Id);
                    //ExpenseLine.Delete(dal, el.Id);
                }
                foreach (Guid i in ids)
                {
                    ExpenseLine.Delete(dal, i);
                }
                db.ExpenseReports.DeleteOnSubmit(report);
            }
            db.SubmitChanges();
        }

        public static void Submit(DAL.DataAccessLayer dal, Guid id)
        {
            DataAccessDataContext db = dal.DataContext;
            ExpenseReport report = db.ExpenseReports.FirstOrDefault(r => r.Id == id);
            if (report != null)
            {
                //db.ExpenseReports.Attach(report);
                report.State = ExpenseReportState.READY;
            }
            db.SubmitChanges();
        }

        public static IEnumerable<ExpenseReport> GetAll(DAL.DataAccessLayer dal, String userId)
        {
            IEnumerable<ExpenseReport> reports = null;
            DataAccessDataContext da = dal.DataContext;

            var query = from e in da.ExpenseReports
                        where e.UserId.Equals(userId)
                        select e;
            if (query != null)
                reports = query.AsEnumerable<ExpenseReport>();

            return reports;
        }

        public static IEnumerable<ExpenseReportState> GetAllStates(DAL.DataAccessLayer dal)
        {
            DataAccessDataContext db = dal.DataContext;
            return from e in db.ExpenseReportStates
                   select e;
        }

        public void Save(DAL.DataAccessLayer dal)
        {
            DataAccessDataContext dc = dal.DataContext;

            var q = from e in dc.ExpenseReports
                    where e.Id.Equals(this.Id)
                    select e;
            int count = q.Count<ExpenseReport>();
            ExpenseReport er = null;
            if (count == 1)
                er = q.First<ExpenseReport>();
            if (er == null)
            {
                dc.ExpenseReports.InsertOnSubmit(this);
            }
            else
            {
                //er = new ExpenseReport();
                er.Name = this.Name;
                er.Comments = this.Comments;
                er.DepartmentId = this.DepartmentId;
            }
            dc.SubmitChanges();

        }

        public static ExpenseReport Get(DAL.DataAccessLayer dal, Guid id)
        {
            DataAccessDataContext da = dal.DataContext;
            return (
                        from e in da.ExpenseReports
                        where e.Id.Equals(id)
                        select e
                    ).Single<ExpenseReport>();
        }

        public void Export(DAL.DataAccessLayer dal, String exportationType)
        {
            DataAccessDataContext da = dal.DataContext;
            ExportationType expType = (
                                from t in da.ExportationTypes
                                where t.Name.Equals(exportationType)
                                select t
                              ).Single<ExportationType>();

            IExportation ee = ExportationFactory.GetExportationType(expType.TypeName, expType.AssemblyString);
            String path = ee.Export(this);
            ExpenseExportation expExport = new ExpenseExportation();
            expExport.Path = path;
            expExport.ReportId = this.Id;
            expExport.Type = exportationType;
            da.ExpenseExportations.InsertOnSubmit(expExport);
            da.SubmitChanges();
        }

        public static String RetrieveJustification(DAL.DataAccessLayer dc, Guid reportid)
        {
            ExpenseReport r = dc.DataContext.ExpenseReports.SingleOrDefault(elem => elem.Id.Equals(reportid));
            bool found = false;

            if (r == null) return null;
            else
            {
                if (r.State == ExpenseReportState.REJECTED)
                {
                    XElement doc, elem;

                    foreach (ExpenseLine line in r.ExpenseLines)
                    {
                        doc = line.ChainState;
                        elem = doc.Elements().SingleOrDefault(node => node.Attribute("authorized").Value.Equals("false"));
                        if (elem != null)
                        {
                            found = true;
                            return elem.Value;
                        }
                    }
                    /* Something wrong went here */
                    if (!found) return null;
                }
                else return null;
            }
            return null;
        }
        
    }
}
